﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace Silvermoon.Controls.Beta
{
    public class ListBoxItemControlGenerator<C> : IDisposable where C : ItemBase
    {
        ListBoxBase listBox;
        private List<C> cachedItems = new List<C>();

        public ListBoxItemControlGenerator(ListBoxBase listBox)
            : base()
        {
            if (listBox == null) throw new ArgumentNullException("listBox");
            this.listBox = listBox;

            listBox.GetItem += new EventHandler<ItemGroupEventArgs>(OnGetItem);
            listBox.DetachItem += new EventHandler<DetachItemEventArgs>(OnDetachItem);
        }

        public void Dispose()
        {
            ReleaseControls();
        }

        public virtual void ReleaseControls()
        {
            foreach (C item in cachedItems) item.Dispose();
            cachedItems.Clear();
        }

        private void OnDetachItem(object sender, DetachItemEventArgs e)
        {
            C item = e.Item as C;
            if (item != null)
            {
                OnReleaseControl(item);
                cachedItems.Add(item);
                e.Item = null;
            }
        }

        private void OnGetItem(object sender, ItemGroupEventArgs e)
        {
            int n = cachedItems.Count - 1;
            C item;
            if (n >= 0)
            {
                item = cachedItems[n];
                cachedItems.RemoveAt(n);
            }
            else
            {
                item = Activator.CreateInstance<C>();
            }

            e.Item = item;
            OnInitializeControl(item, e.Index, e.Group);
        }

        protected virtual void OnReleaseControl(C item)
        {
            if (ReleaseControl != null)
            {
                ListBoxItemControlGeneratorEventArgs<C> e = new ListBoxItemControlGeneratorEventArgs<C>();
                e.Control = item;
                ReleaseControl(this, e);
            }
        }


        protected virtual void OnInitializeControl(C item, int index, ItemGroupBase group)
        {
            if (InitializeControl != null)
            {
                ListBoxItemControlGeneratorEventArgs<C> e = new ListBoxItemControlGeneratorEventArgs<C>();
                e.Control = item;
                e.Index = index;
                e.Group = group;
                InitializeControl(this, e);
            }
        }

        public event EventHandler<ListBoxItemControlGeneratorEventArgs<C>> InitializeControl;
        public event EventHandler<ListBoxItemControlGeneratorEventArgs<C>> ReleaseControl;

    }

    public class ListBoxItemControlGeneratorEventArgs<C> : EventArgs where C : Control
    {
        public C Control { get; set; }
        public int Index { get; set; }
        public ItemGroupBase Group { get; set; }
    }
}
